#include <rtdef.h>
#include <rtthread.h>
#include "EEPROM.h"
#include "MQ.h"

#define DRV_DEBUG 1
#define LOG_TAG     "eeprom.spi"
#include <drv_log.h>

struct rt_i2c_bus_device *i2c_ee_dev;
rt_device_t EEPROMdev;
rt_mq_t eeprom_mq;

// 提交 Flash 操作请求
static rt_err_t eeprom_submit_request(eeprom_req_t *req)
{
    if( eeprom_mq ==RT_NULL)
    {
        return RT_ERROR;
    }
    if( i2c_ee_dev == RT_NULL)
    {
        return RT_ERROR;
    }
    return rt_mq_send(eeprom_mq, &req, sizeof(req));
}

// 同步写入接口
rt_err_t eeprom_write_sync(rt_uint32_t addr, const void *data, rt_uint32_t size)
{
    rt_err_t result;
    struct rt_semaphore sem;
    eeprom_req_t req = {
        .op_type = EEPROM_OP_WRITE,
        .addr = addr,
        .size = size,
        .data = (void*)data,
        .completion_sem = &sem,
        .result = RT_EOK
    };
    
    // 初始化信号量
    rt_sem_init(&sem, "eeprom_sync", 0, RT_IPC_FLAG_FIFO);
    
    // 提交请求
    result = eeprom_submit_request(&req);
    if (result != RT_EOK) {
        rt_sem_detach(&sem);
        return result;
    }
    
    // 等待操作完成
    rt_sem_take(&sem, RT_WAITING_FOREVER);
    rt_sem_detach(&sem);
    
    return req.result;
}

// 同步读接口
rt_err_t eeprom_Read_sync(rt_uint32_t addr, const void *data, rt_uint32_t size)
{
    rt_err_t result;
    struct rt_semaphore sem;
    eeprom_req_t req = {
        .op_type = EEPROM_OP_READ,
        .addr = addr,
        .size = size,
        .data = (void*)data,
        .completion_sem = &sem,
        .result = RT_EOK
    };
    
    // 初始化信号量
    rt_sem_init(&sem, "eeprom_sync", 0, RT_IPC_FLAG_FIFO);
    
    // 提交请求
    result = eeprom_submit_request(&req);
    if (result != RT_EOK) {
        rt_sem_detach(&sem);
        return result;
    }
    
    // 等待操作完成
    rt_sem_take(&sem, RT_WAITING_FOREVER);
    rt_sem_detach(&sem);
    
    return req.result;
}

void EEPROM_thread_entry(void *parameter)
{
    rt_err_t result;
    eeprom_req_t *req;
    // 初始化消息队列
    eeprom_mq = rt_mq_create("eeprom_mq", sizeof(eeprom_req_t*), 10, RT_IPC_FLAG_FIFO);
    if( eeprom_mq == RT_NULL)
    {
        LOG_I("eeprom_mq dev open error\r\n");
    }
    EEPROMdev = rt_device_find("i2c2_EEPROM");
    if (EEPROMdev)
    {
        rt_thread_mdelay(1000);
        rt_device_open(EEPROMdev, RT_DEVICE_OFLAG_RDWR);
        i2c_ee_dev = (struct rt_i2c_bus_device *)EEPROMdev;
        rt_kprintf("successful: i2c2_EEPROM Device successful \n");
    }
    else
    {
        LOG_I("i2c_ee_dev dev open error\r\n");
    }
    
    while(1)
    {
        if ( rt_mq_recv(eeprom_mq, &req, sizeof(req), RT_WAITING_FOREVER )) 
        {
            switch (req->op_type) 
            {
                case EEPROM_OP_ERASE://擦除
                    LOG_I("EEPROM EEPROM_OP_ERASE");
                    break;
                case EEPROM_OP_WRITE://写
                    LOG_I("EEPROM EEPROM_OP_WRITE");
                    WriteXX24XXX(CS_SPI_256401, req->addr, req->size, req->data );
                    break;
                case EEPROM_OP_READ://读
                    LOG_I("EEPROM EEPROM_OP_READ");
                    ReadXX24XXX(CS_SPI_256401, req->addr, req->size, req->data );
                    break;
                case EEPROM_OP_VERIFY:
                    break;
                default:
                    break;
            }
            if (req->completion_sem != RT_NULL) 
            {
                rt_sem_release(req->completion_sem);
            }
        }
    }
}